import ButtonFilled from 'components/ButtonFilled';
import RoundedInput from 'components/RoundedInput';
import RoundedSelect from 'components/RoundedSelect';
import Grid from '@material-ui/core/Grid';
import { useContract } from 'containers/DrizzleProvider/hooks';
import { useWeb3 } from 'containers/ConnectionProvider/hooks';
import OldPickleGaugeAbi from 'abi/oldPickleGauge.json';
import {
  withdrawFromVault,
  withdrawAllFromVault,
  depositToVault,
  depositPickleSLPInFarm,
  exitOldPickleGauge,
} from 'containers/Vaults/actions';
import React, { useState, useEffect, useMemo } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import styled from 'styled-components';
import BigNumber from 'bignumber.js';
import { first } from 'lodash';
import useMediaQuery from '@material-ui/core/useMediaQuery';
import { selectTokenAllowance } from 'containers/App/selectors';
import { selectMigrationData } from 'containers/Vaults/selectors';
import {
  selectZapperVaults,
  selectZapperTokens,
  selectZapperBalances,
  selectZapperError,
} from 'containers/Zapper/selectors';
import { zapIn, zapOut, migratePickleGauge } from 'containers/Zapper/actions';
import { DEFAULT_SLIPPAGE } from 'containers/Zapper/constants';
import BackscratcherClaim from 'components/BackscratcherClaim';
import MigrateVault from 'components/MigrateVault';
import {
  BACKSCRATCHER_ADDRESS,
  MASTER_CHEF_ADDRESS, //
  V2_WETH_VAULT_ADDRESS,
  YVBOOST_ADDRESS,
  YVBOOST_ETH_PJAR,
  PICKLE_GAUGE_ADDRESS,
  OLD_PICKLE_GAUGE_ADDRESS,
  ZAP_MIGRATE_PICKLE_ADDRESS,
  YALINK_VAULT_ADDRESS,
  LINK_VAULT_ADDRESS,
} from 'containers/Vaults/constants';
import Box from 'components/Box';
import Text from 'components/Text';
import Label from 'components/Label';
import PickleJarAbi2 from 'abi/pickleJar2.json';
import PickleGaugeAbi from 'abi/pickleGauge.json';
import ZapPickleMigrateAbi from 'abi/zapPickleMigrate.json';
const MaxWrapper = styled.div`
  cursor: pointer;
  display: flex;
  align-items: center;
  color: initial;
  position: relative;
  top: -2px;
`;

const PickleControl = styled.div`
  margin-top: 1rem;
  margin-bottom: 1rem;
`;

const StyledRoundedInput = styled(RoundedInput)`
  width: 100%;
`;
const StyledRoundedSelect = styled(RoundedSelect)`
  width: 100%;
`;

const ActionGroup = styled(Box)`
  display: ${(props) => (props.hide ? 'none' : 'flex')};
  flex-direction: ${(props) => props.direction || 'column'};
`;

const ButtonGroup = styled(Box)`
  display: flex;
  justify-content: start;
  align-items: center;
`;

const Wrapper = styled.div`
  display: flex;
  width: 100%;
`;

const StyledErrorMessage = styled(Text)`
  color: ${(props) => props.theme.blocksRed};
`;

const getNormalizedAmount = (amount, decimals) =>
  new BigNumber(amount).dividedBy(10 ** decimals).toFixed(2);

// 金库控制器
export default function VaultControls(props) {
  //
  const {
    vault,
    vaultBalance,
    walletBalance,
    balanceOf,
    tokenBalance,
    pickleContractsData, // pickleContractsData 合约的pickle数据
    balanceDecimalPlacesCount,
    account,
    oldPickleGaugeBalance,
    yvBOOSTBalance,
  } = props;

  const {
    address: vaultAddress,
    totalAssets,
    token,
    decimals,
    pureEthereum,
    depositLimit,
    zapAddress,
    emergencyShutdown,
  } = vault;
  const yvBoostContract = useContract(vaultAddress);

  const v2Vault = vault.type === 'v2' || vault.apiVersion;
  const vaultIsBackscratcher = vault.address === BACKSCRATCHER_ADDRESS;
  const vaultIsPickle = vault.address === MASTER_CHEF_ADDRESS;
  const vaultIsYvBoost = vault.address === YVBOOST_ADDRESS;
  const hideZapOut = [
    YALINK_VAULT_ADDRESS.toLocaleLowerCase(),
    LINK_VAULT_ADDRESS.toLocaleLowerCase(),
  ].includes(vault.address.toLowerCase());

  // 金库的余额，也是可以提现的额度
  let vaultBalanceOf;
  if (v2Vault) {

    vaultBalanceOf = new BigNumber(balanceOf)
      .times(vault.pricePerShare / 10 ** decimals)
      .toFixed();
  } else {
    vaultBalanceOf = new BigNumber(balanceOf)
      .times(vault.getPricePerFullShare / 10 ** 18)
      .toFixed();
  }

  // console.log('111', balanceOf);

  // console.log('222', vaultBalanceOf);

  const isScreenMd = useMediaQuery('(min-width:960px)');
  const dispatch = useDispatch();
  let vaultContract = useContract(vaultAddress);
  const zapContract = useContract(zapAddress);
  if (zapContract) {
    vaultContract = { ...vaultContract, zapContract };
  }
  const migrationData = useSelector(selectMigrationData);
  const isMigratable = !!migrationData[vaultAddress];

  // ----- ZAPPER
  const web3 = useWeb3();
  const zapperVaults = useSelector(selectZapperVaults());
  const zapperTokens = useSelector(selectZapperTokens());
  const zapperBalances = useSelector(selectZapperBalances());
  const zapperError = useSelector(selectZapperError());
  const zapperVaultData = zapperVaults[vaultAddress.toLowerCase()];
  const isZappable = !!zapperVaultData;
  const isSupportedToken = ({ address, hide }) =>
    address !== token.address && !hide && !!zapperTokens[address];
  const isSameToken = ({ label, address }) =>
    (vaultAddress === V2_WETH_VAULT_ADDRESS &&
      (label === 'ETH' || label === 'WETH')) ||
    address === token.address.toLowerCase();
  const supportedTokenOptions = Object.values(zapperBalances)
    .filter(isSupportedToken)
    .filter((option) => !isSameToken(option))
    .map(({ address, label, img }) => ({
      value: address,
      label,
      icon: `https://zapper.fi/images/${img}`,
    }));
  supportedTokenOptions.unshift({
    value: token.address,
    // eslint-disable-next-line no-nested-ternary
    label: pureEthereum
      ? 'ETH'
      : token.displayName
        ? token.displayName
        : token.symbol.replace('yveCRV-DAO', 'yveCRV'),
    icon: `https://raw.githack.com/iearn-finance/yearn-assets/master/icons/tokens/${token.address}/logo-128.png`,
  });
  const [selectedSellToken, setSelectedSellToken] = useState(
    first(supportedTokenOptions),
  );
  const sellToken = zapperBalances[selectedSellToken.value];

  const willZapIn =
    selectedSellToken && selectedSellToken.value !== token.address;

  // ~~~~

  const tokenContract = useContract(token.address);
  const [pickleUnstakeGweiAmount, setPickleUnstakeGweiAmount] = useState(0);
  const [pickleUnstakeAmount, setPickleUnstakeAmount] = useState(0);

  const [pickleDepositGweiAmount, setPickleDepositGweiAmount] = useState(0);
  const [pickleDepositAmount, setPickleDepositAmount] = useState(0);

  const [oldPickleDepositGweiAmount, setOldPickleDepositGweiAmount] = useState(
    0,
  );
  const [oldPickleDepositAmount, setOldPickleDepositAmount] = useState(0);

  const [withdrawalAmount, setWithdrawalAmount] = useState(0);

  // 存款数量，更新存款数量方法
  const [depositAmount, setDepositAmount] = useState(0);

  const [withdrawalGweiAmount, setWithdrawalGweiAmount] = useState(0);
  const [depositGweiAmount, setDepositGweiAmount] = useState(0);
  const zapperImgUrl = 'https://zapper.fi/images/';

  const tmpWithdrawTokens = [];
  [
    {
      label: 'ETH',
      address: '0x0000000000000000000000000000000000000000',
      icon: `${zapperImgUrl}ETH-icon.png`,
      value: 'ETH',
    },
    {
      label: 'DAI',
      address: '0x6b175474e89094c44da98b954eedeac495271d0f',
      icon: `${zapperImgUrl}DAI-icon.png`,
      value: 'DAI',
    },
    {
      label: 'USDC',
      address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
      icon: `${zapperImgUrl}USDC-icon.png`,
      value: 'USDC',
    },
    {
      label: 'USDT',
      address: '0xdac17f958d2ee523a2206206994597c13d831ec7',
      icon: `${zapperImgUrl}USDT-icon.png`,
      value: 'USDT',
    },
    {
      label: 'WBTC',
      address: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599',
      icon: `${zapperImgUrl}WBTC-icon.png`,
      value: 'WBTC',
    },
  ].map((t) => {
    if (t.label !== vault.displayName) {
      tmpWithdrawTokens.push(t);
    }
    return t;
  });

  const currentVaultToken = {
    label: vault.displayName,
    address: vault.token.address,
    isVault: true,
    icon: vault.token.icon,
    value: vault.displayName,
  };
  if (vault.displayName === 'yvBOOST') {
    tmpWithdrawTokens.unshift({
      label: 'yveCRV',
      address: vault.token.address,
      isVault: true,
      icon:
        'https://raw.githubusercontent.com/iearn-finance/yearn-assets/master/icons/tokens/0xc5bDdf9843308380375a611c18B50Fb9341f502A/logo-128.png',
      value: vault.displayName,
    });
  } else {
    tmpWithdrawTokens.unshift(currentVaultToken);
  }
  const withdrawTokens = hideZapOut ? [currentVaultToken] : tmpWithdrawTokens;

  const [selectedWithdrawToken, setSelectedWithdrawToken] = useState(
    withdrawTokens[0],
  );

  const tokenContractAddress =
    (tokenContract && tokenContract.address) || '0x0';
  const vaultContractAddress =
    (vaultContract && vaultContract.address) || '0x0';
  const tokenAllowance = useSelector(
    selectTokenAllowance(tokenContractAddress, vaultContractAddress),
  );

  const depositLimitBN = useMemo(() => new BigNumber(depositLimit), [
    depositLimit,
  ]);

  const totalAssetsBN = useMemo(() => new BigNumber(totalAssets), [
    totalAssets,
  ]);

  const approvalExplainer =
    'Before depositing for the first time, users must submit an approval transaction to allow Yearn to accept your funds. Once this approval transaction has confirmed, you can deposit any amount, forever, from this address.';

  const depositsDisabled = useMemo(() => {
    if (vault.type === 'v2') {
      if (
        !willZapIn &&
        totalAssetsBN.plus(depositGweiAmount).gte(depositLimitBN)
      ) {
        console.log('vault limit reached', vault.symbol);
        return 'Vault deposit limit reached.';
      }
      // fix: disable deposit button if value is 0
      // note: resolves issue #252 from iearn-finance repo
      // this issue only affects v2 & is mis-ticketed as v1 (iearn-finance)
      if (depositGweiAmount <= 0) {
        return 'Value must be greater than 0.';
      }
    } else if (
      vault.type === 'v1' &&
      vault.address === '0xBA2E7Fed597fd0E3e70f5130BcDbbFE06bB94fe1'
    ) {
      console.log('vault address', vault.symbol);
      return 'Inactive with YIP-56: Buyback and Build';
    }

    if (emergencyShutdown) {
      console.log('emergency', vault.symbol);
      return 'Vault deposits temporarily disabled';
    }
    //console.log('ok deposit', vault.symbol, depositAmount);

    return undefined;
  }, [depositAmount, totalAssets, depositLimit, emergencyShutdown]);

  // 初始状态
  useEffect(() => {
    setDepositAmount(0);
    setPickleDepositAmount(0);
    setWithdrawalAmount(0);
    setDepositGweiAmount(0);
    setWithdrawalGweiAmount(0);
  }, [walletBalance, vaultBalance]);

  const [
    yvBOOSTPickleGaugeAllowance,
    setYvBOOSTPickleGaugeAllowance,
  ] = useState(0);
  const [yvBOOSTPickleJarAllowance, setYvBOOSTPickleJarAllowance] = useState(0);

  //
  useEffect(() => {
    // 查询余额的方法
    const getBalance = async () => {
      if (
        pickleContractsData &&
        pickleContractsData.pickleJarContract &&
        account
      ) {
        try {
          const ap = await pickleContractsData.pickleJarContract.methods
            .allowance(account, ZAP_MIGRATE_PICKLE_ADDRESS)
            .call();
          setYvBOOSTPickleJarAllowance(ap);
        } catch {
          // no worries
        }
      }
      if (vaultIsYvBoost && tokenContract && vault && vault.address) {
        try {
          const ha = await tokenContract.methods
            .allowance(account, vault.address)
            .call();

          if (ha && ha > 0) {
            vault.hasAllowance = true;
          }
        } catch {
          // no worries
        }
      }
      try {
        const yvBoostETHContract = new web3.eth.Contract(
          PickleJarAbi2,
          YVBOOST_ETH_PJAR,
        );
        const allowance = await yvBoostETHContract.methods
          .allowance(account, PICKLE_GAUGE_ADDRESS)
          .call();

        setYvBOOSTPickleGaugeAllowance(allowance);
      } catch {
        // no worries
      }
    };
    // 查询余额
    getBalance();
  });

  const migratePickleGaugeCall = async () => {
    // 迁移pickleguage的方法调用
    const zapPickleMigrateContract = new web3.eth.Contract(
      ZapPickleMigrateAbi,
      ZAP_MIGRATE_PICKLE_ADDRESS,
    );
    dispatch(
      migratePickleGauge({
        pickleDepositAmount: oldPickleDepositGweiAmount,
        zapPickleMigrateContract,
        tokenContract: pickleContractsData.pickleJarContract,
        allowance: yvBOOSTPickleJarAllowance,
      }),
    );
  };

  const exitOldPickleGaugeCall = () => {
    // 退出pickleguage的方法调用
    const oldPickleGaugeContract = new web3.eth.Contract(
      OldPickleGaugeAbi,
      OLD_PICKLE_GAUGE_ADDRESS,
    );

    dispatch(exitOldPickleGauge({ oldPickleGaugeContract }));
  };

  // 没有质押的额度
  const unstakeMasterChef = (maxAmount) => {
    const unstakeParams = {
      vaultContract: pickleContractsData.masterChefContract,
      withdrawalAmount: BigNumber(maxAmount),
      decimals: pickleContractsData.decimals,
      pureEthereum,
      unstakePickle: true,
    };
    dispatch(withdrawFromVault(unstakeParams));
  };

  const withdraw = () => {
    // 提现的方法
    if (
      selectedWithdrawToken.address.toLowerCase() ===
      vault.token.address.toLowerCase()
    ) {
      dispatch(
        withdrawFromVault({
          vaultContract,
          withdrawalAmount: withdrawalGweiAmount,
          decimals,
          pureEthereum,
        }),
      );
    } else {
      dispatch(
        zapOut({
          web3,
          slippagePercentage: DEFAULT_SLIPPAGE,
          vaultContract,
          withdrawalAmount: withdrawalGweiAmount,
          decimals,
          selectedWithdrawToken,
          pureEthereum,
        }),
      );
    }
  };

  const withdrawAll = () => {
    // 全部提现的方法
    dispatch(
      withdrawAllFromVault({
        vaultContract,
        pureEthereum,
        balanceOf,
      }),
    );
  };

  const depositPickleFarm = () => {
    // 存入pickle做farm
    const yvBoostETHContract = new web3.eth.Contract(
      PickleJarAbi2,
      YVBOOST_ETH_PJAR,
    );
    const pickleGaugeContract = new web3.eth.Contract(
      PickleGaugeAbi,
      PICKLE_GAUGE_ADDRESS,
    );

    const payload = {
      vaultContract: pickleGaugeContract,
      tokenContract: yvBoostETHContract,
      depositAmount: pickleDepositGweiAmount,
      allowance: yvBOOSTPickleGaugeAllowance,
    };

    dispatch(depositPickleSLPInFarm(payload));
  };

  const deposit = () => {
    // 存款
    console.log(`Depositing:`, depositGweiAmount);
    dispatch(
      depositToVault({
        vaultContract,
        tokenContract,
        depositAmount: depositGweiAmount,
        decimals,
        pureEthereum,
        hasAllowance: vault.hasAllowance,
      }),
    );
  };

  const zapperZap = () => {
    // zapper调用
    dispatch(
      zapIn({
        web3,
        poolAddress: zapperVaultData.address,
        sellTokenAddress: sellToken.address,
        sellAmount: depositGweiAmount,
        slippagePercentage: DEFAULT_SLIPPAGE,
      }),
    );
  };

  const zapperZapYvBoostEthLP = () => {
    let addr = null;
    if (sellToken && sellToken.address) {
      addr = sellToken.address;
    } else if (selectedSellToken && selectedSellToken.address) {
      addr = selectedSellToken.address;
    } else if (token && token.address) {
      addr = token.address;
    }
    if (addr) {
      const payload = {
        web3,
        poolAddress: YVBOOST_ETH_PJAR.toLowerCase(),
        sellTokenAddress: addr,
        sellAmount: depositGweiAmount,
        slippagePercentage: DEFAULT_SLIPPAGE,
        protocol: 'pickle',
      };
      dispatch(zapIn(payload));
    }
  };

  let vaultControlsWrapper;

  if (vaultIsPickle && !vault.isYVBoost) {
    //console.log('~~~~>1:', vault.symbol);
    // 如果是pickle金库，但不是YBBoost金库

    // let stakedMaxAmount = 0;
    // stakedMaxAmount = pickleContractsData.pickleMasterChefDepositedRaw;
    // const customWalletBalance =
    //   walletBalance > oldPickleGaugeBalance
    //     ? walletBalance
    //     : oldPickleGaugeBalance;
    const useOldPickleGauge = walletBalance < oldPickleGaugeBalance;
    // 默认是0
    let pickleMaxAmount = 0;
    let pickleBalance = 0;

    // 根据pickleContractsData的值覆盖上述的pickleMaxAmount ，pickleBalance
    if (
      pickleContractsData &&
      pickleContractsData.pickleMasterChefDepositedRaw
    ) {
      pickleMaxAmount = pickleContractsData.pickleMasterChefDepositedRaw; //
      pickleBalance = pickleContractsData.pickleMasterChefDeposited;
    }

    // pickle描述，maxAmount是available按钮中的最大可以存款的额度 Max deposit
    //
    const pickleDescriptions = [
      {
        balance: pickleBalance,
        main: '1. You have to unstake your LP Tokens',
        sub: 'Available Pickle SLP',
        buttonLabel: 'Unstake',
        maxAmount: pickleMaxAmount,
        amount: pickleUnstakeAmount,
        amountSetter: setPickleUnstakeAmount,
        gweiAmountSetter: setPickleUnstakeGweiAmount,
        buttonFunction: useOldPickleGauge
          ? exitOldPickleGaugeCall
          : () => {
            unstakeMasterChef(pickleMaxAmount);
          },
        buttonDisable:
          pickleUnstakeGweiAmount >
          pickleContractsData.pickleMasterChefDepositedRaw ||
          pickleBalance === 0 ||
          pickleBalance === '0',
        disableAmountField: true,
        hideBalance: true,
        disabledStyle: {
          background: '#1d265f',
          color: 'white',
        },
      },
      {
        balance: walletBalance,
        main:
          '2. Then approve and migrate from yveCRV-ETH LP into yvBOOST-ETH LP to enjoy 🍣 and 🥒 rewards',
        sub: 'Available SLP: ',
        buttonLabel: yvBOOSTPickleJarAllowance > 0 ? 'Migrate' : 'Approve',
        maxAmount: new BigNumber(walletBalance).times(10 ** 18),
        amount: oldPickleDepositAmount,
        amountSetter: setOldPickleDepositAmount,
        gweiAmountSetter: setOldPickleDepositGweiAmount,
        buttonFunction: migratePickleGaugeCall,
        buttonDisable:
          oldPickleDepositGweiAmount >
          new BigNumber(walletBalance).times(10 ** 18),
      },
      {
        balance: new BigNumber(yvBOOSTBalance).dividedBy(10 ** 18).toFixed(2),
        main:
          '3. Last step! After the previous transaction completes, approve and stake your Pickle LPs using the box below',
        sub: 'Available Pickle SLP: ',
        buttonLabel: yvBOOSTPickleGaugeAllowance > 0 ? 'Stake' : 'Approve',
        maxAmount: yvBOOSTBalance,
        amount: pickleDepositAmount,
        amountSetter: setPickleDepositAmount,
        gweiAmountSetter: setPickleDepositGweiAmount,
        buttonFunction: depositPickleFarm,
        buttonDisable: pickleDepositGweiAmount > yvBOOSTBalance,
      },
    ];

    // pickle注释
    const pickleNote =
      'Note: If you want to claim PICKLE 🥒 rewards or withdraw your yvBOOST-ETH SLP, please, use UI at';
    const pickleNoteLink = 'https://app.pickle.finance/farms';

    vaultControlsWrapper = (
      <Wrapper>
        <Box display="flex" flexDirection="column" width={1}>
          {pickleDescriptions.map((description,index) => (
            <div key={index}>
              <Label fontSize={16}>{description.main}</Label>
              <PickleControl>
                <Grid item xs={12} md={6}>
                  <Balance
                    amount={description.balance}
                    prefix={description.sub}
                    hideBalance={description.hideBalance}
                  />
                  <ActionGroup
                    direction={isScreenMd ? 'row' : 'column'}
                    alignItems="center"
                  >
                    <Box width={1}>
                      {/* 锁定的数量区域 */}
                      <AmountField
                        disabled={description.disableAmountField}
                        amount={
                          description.disableAmountField
                            ? new BigNumber(description.maxAmount).dividedBy(
                              10 ** 18,
                            )
                            : description.amount
                        }
                        amountSetter={description.amountSetter}
                        gweiAmountSetter={description.gweiAmountSetter}
                        maxAmount={description.maxAmount} // 余额
                        decimals={decimals}
                        placeholder="Amount"
                        hideMaxButton={description.hideBalance}
                        disabledStyle={description.disabledStyle}
                      />
                    </Box>
                    <Box ml={isScreenMd ? 5 : 0} width={isScreenMd ? '30%' : 1}>
                      {/* 点击按钮区域 */}
                      <ActionButton
                        disabled={description.buttonDisable}
                        handler={description.buttonFunction}
                        text={description.buttonLabel}
                        title={description.buttonLabel}
                        showTooltip
                        tooltipText={
                          depositsDisabled ||
                          'Connect your wallet to deposit into vault'
                        }
                      />
                    </Box>
                  </ActionGroup>
                </Grid>
              </PickleControl>
            </div>
          ))}
          <Label fontSize={16}> {pickleNote} </Label>
          <a href={pickleNoteLink}> {pickleNoteLink} </a>
        </Box>
      </Wrapper>
    );
  } else if (vault.isYVBoost) {
    //console.log('~~~~>2:', vault.symbol);

    // 如果是YVBoost
    vaultControlsWrapper = (
      <Wrapper>
        <Box display="flex" flexDirection="column" width={1}>
          <ActionGroup direction={isScreenMd ? 'row' : 'column'}>
            <Grid container spacing={1}>
              <Grid item xs={12} md={12}>
                <Box>
                  <Balance
                    amount={sellToken ? sellToken.balance : walletBalance}
                    prefix={`Available ${selectedSellToken
                      ? selectedSellToken.label
                      : sellToken.symbol
                      }: `}
                  />
                </Box>
              </Grid>
              <Grid item xs={12} md={5}>
                <Box>
                  <SelectField
                    defaultValue={selectedSellToken}
                    onChange={(value) => {
                      setDepositAmount(0);
                      setSelectedSellToken(value);
                    }}
                    flexGrow={1}
                    options={supportedTokenOptions}
                  />
                </Box>
              </Grid>
              <Grid item xs={12} md={3}>
                <ButtonGroup width={1} style={{ imarginTop: '' }}>
                  <Box>
                    {/* 存款区域 */}

                    <AmountField
                      amount={depositAmount}
                      amountSetter={setDepositAmount}
                      gweiAmountSetter={setDepositGweiAmount}
                      maxAmount={
                        sellToken ? sellToken.balanceRaw : tokenBalance
                      }
                      decimals={sellToken ? sellToken.decimals : decimals}
                    />
                  </Box>
                </ButtonGroup>
              </Grid>
              <Grid item xs={12} md={4}>
                <ButtonGroup width={1} style={{ marginTop: '-10px' }}>
                  <ActionButton
                    className="action-button dark"
                    disabled={
                      depositGweiAmount >
                      (sellToken ? sellToken.balanceRaw : tokenBalance)
                    }
                    handler={() => zapperZapYvBoostEthLP()}
                    text={
                      (tokenAllowance !== undefined &&
                        tokenAllowance !== '0') ||
                      pureEthereum > 0 ||
                      'Deposit'
                    }
                    title="Deposit into vault"
                    showTooltip
                    tooltipText={
                      depositsDisabled ||
                      'Connect your wallet to deposit into vault'
                    }
                  />
                  {zapperError &&
                    zapperError.poolAddress === vaultAddress.toLowerCase() && (
                      <StyledErrorMessage>
                        {zapperError.message}
                      </StyledErrorMessage>
                    )}{' '}
                </ButtonGroup>
              </Grid>
            </Grid>
          </ActionGroup>
          <ActionGroup direction={isScreenMd ? 'row' : 'column'}>
            <Grid container spacing={1}>
              <Grid item xs={12} md={8}>
                <Box>
                  <Balance
                    amount={new BigNumber(yvBOOSTBalance)
                      .dividedBy(10 ** 18)
                      .toFixed(2)}
                    prefix="Vault balance: "
                  />
                </Box>{' '}
                <Box>
                  {/* pickle存款区域 */}
                  <AmountField
                    amount={pickleDepositAmount}
                    amountSetter={setPickleDepositAmount}
                    gweiAmountSetter={setPickleDepositGweiAmount}
                    maxAmount={yvBOOSTBalance}
                    decimals={18}
                  />
                </Box>
              </Grid>
              <Grid item xs={12} md={4}>
                <ButtonGroup width={1} style={{ marginTop: '15px' }}>
                  <ActionButton
                    className="action-button dark"
                    disabled={yvBOOSTBalance === 0}
                    handler={() => depositPickleFarm()}
                    text={
                      !yvBOOSTPickleGaugeAllowance ||
                        yvBOOSTPickleGaugeAllowance === 0 ||
                        yvBOOSTPickleGaugeAllowance === '0'
                        ? 'Approve'
                        : 'Deposit'
                    }
                    title="Deposit into vault"
                    showTooltip
                    tooltipText={
                      depositsDisabled ||
                      'Connect your wallet to deposit into vault'
                    }
                  />
                </ButtonGroup>
              </Grid>
            </Grid>
          </ActionGroup>
        </Box>
      </Wrapper>
    );
  } else if (vaultIsBackscratcher) {
    // 如果金库是后台抓取
    //console.log('~~~~>3:', vault.symbol);

    const depositHasBeenApproved =
      (tokenAllowance !== undefined && tokenAllowance !== '0') ||
      pureEthereum > 0;
    vaultControlsWrapper = (
      <Wrapper>
        <Box display="flex" flexDirection="column" width={1}>
          <Balance amount={walletBalance} prefix="Available CRV: " />
          <ActionGroup
            direction={isScreenMd ? 'row' : 'column'}
            alignItems="center"
          >
            <Box width={1}>
              {/* 后台抓取金库存款区域 */}
              <AmountField
                amount={depositAmount}
                amountSetter={setDepositAmount}
                gweiAmountSetter={setDepositGweiAmount}
                maxAmount={tokenBalance}
                decimals={decimals}
                placeholder="Amount"
              />
            </Box>
            <Box ml={isScreenMd ? 5 : 0} width={isScreenMd ? '30%' : 1}>
              <ActionButton
                className="action-button dark"
                disabled={
                  !vaultContract || !tokenContract || !!depositsDisabled
                }
                handler={deposit}
                text={depositHasBeenApproved ? 'Deposit' : 'Approve'}
                title="Deposit into vault"
                showTooltipWhenDisabled
                disabledTooltipText={
                  depositsDisabled ||
                  'Connect your wallet to deposit into vault'
                }
                showTooltipWhenEnabled={!depositHasBeenApproved}
                enabledTooltipText={approvalExplainer}
              />
            </Box>
          </ActionGroup>
          <BackscratcherClaim
            isScreenMd={isScreenMd}
            vaultAddress={vaultAddress}
          />
        </Box>
      </Wrapper>
    );
  } else if (vaultIsYvBoost) {
    //console.log('~~~~>4:', vault.symbol);

    // 如果金库是YvBoost
    vaultControlsWrapper = (
      <Wrapper>
        <Box display="flex" flexDirection="column">
          <ActionGroup direction={isScreenMd ? 'row' : 'column'}>
            <Grid container spacing={1}>
              <Grid item xs={12} md={12}>
                <Box>
                  <Balance
                    amount={
                      isZappable && sellToken
                        ? sellToken.balance
                        : walletBalance
                    }
                    prefix={`Available ${selectedSellToken
                      ? selectedSellToken.label
                      : sellToken.symbol
                      }: `}
                  />
                </Box>
              </Grid>
              <Grid item xs={12} md={5}>
                <Box>
                  <SelectField
                    defaultValue={selectedSellToken}
                    onChange={(value) => {
                      setDepositAmount(0);
                      setSelectedSellToken(value);
                    }}
                    flexGrow={1}
                    options={supportedTokenOptions}
                  />
                </Box>
              </Grid>
              <Grid item xs={12} md={3}>
                <ButtonGroup width={1}>
                  <Box>
                    {/* YvBoost存款区域 */}
                    <AmountField
                      amount={depositAmount}
                      amountSetter={setDepositAmount}
                      gweiAmountSetter={setDepositGweiAmount}
                      maxAmount={
                        isZappable && sellToken
                          ? sellToken.balanceRaw
                          : tokenBalance
                      }
                      decimals={
                        isZappable && sellToken ? sellToken.decimals : decimals
                      }
                    />
                  </Box>
                </ButtonGroup>
              </Grid>
              <Grid item xs={12} md={4}>
                <ButtonGroup width={1} style={{ marginTop: '-10px' }}>
                  <ActionButton
                    className="action-button dark"
                    disabled={
                      !yvBoostContract || !tokenContract || !!depositsDisabled
                    }
                    handler={() => (willZapIn ? zapperZap() : deposit())}
                    text={
                      vault.hasAllowance || pureEthereum > 0 || willZapIn
                        ? 'Deposit'
                        : 'Approve'
                    }
                    title="Deposit into vault"
                    showTooltip
                    tooltipText={
                      depositsDisabled ||
                      'Connect your wallet to deposit into vault'
                    }
                  />
                  {zapperError &&
                    zapperError.poolAddress === vaultAddress.toLowerCase() && (
                      <StyledErrorMessage>
                        {zapperError.message}
                      </StyledErrorMessage>
                    )}
                </ButtonGroup>
              </Grid>
            </Grid>
          </ActionGroup>

          <ActionGroup direction={isScreenMd ? 'row' : 'column'}>
            <Grid container spacing={1}>
              <Grid item xs={12} md={12}>
                <Box>
                  <Balance amount={vaultBalance} prefix="Vault balance: " />
                </Box>
              </Grid>
              <Grid item xs={12} md={5}>
                <Box>
                  <SelectField
                    defaultValue={withdrawTokens[0]}
                    value={selectedWithdrawToken}
                    options={withdrawTokens}
                    onChange={(newValue) => {
                      setSelectedWithdrawToken(newValue);
                    }}
                  />
                </Box>
              </Grid>
              <Grid item xs={12} md={3}>
                <ButtonGroup width={1}>
                  <Box>
                    {/* 提现1 vaultIsYvBoost */}
                    <AmountField
                      amount={withdrawalAmount}
                      amountSetter={setWithdrawalAmount}
                      gweiAmountSetter={setWithdrawalGweiAmount}
                      maxAmount={vaultBalanceOf}
                      decimals={decimals}
                    />
                  </Box>
                </ButtonGroup>
              </Grid>
              <Grid item xs={12} md={4}>
                <ButtonGroup width={1} style={{ marginTop: '-10px' }}>
                  <ActionButton
                    className="action-button dark"
                    disabled={!vaultContract || !tokenContract}
                    handler={withdraw}
                    text="Withdraw"
                    title="Withdraw from vault"
                    showTooltip
                    tooltipText="Connect your wallet to withdraw from vault"
                  />
                </ButtonGroup>
              </Grid>
            </Grid>
          </ActionGroup>
        </Box>
      </Wrapper>
    );
  } else {
    // 默认的金库

    // console.log('<=====', vault.symbol, vaultBalanceOf);
    const depositHasBeenApproved =
      (tokenAllowance !== undefined && tokenAllowance !== '0') ||
      pureEthereum > 0 ||
      willZapIn;
    vaultControlsWrapper = (
      <Wrapper>
        <Box
          display="flex"
          flexDirection={isScreenMd ? 'row' : 'column'}
          width={1}
        >
          <ActionGroup
            direction={isScreenMd ? 'row' : 'column'}
            ml={isScreenMd ? '60px' : '0px'}
          >
            <Box display="flex" flexDirection="column">
              <Balance
                amount={
                  isZappable && sellToken ? sellToken.balance : walletBalance
                }
                prefix="Available: "
                decimalPlaces={balanceDecimalPlacesCount}
              />
              <Box
                display="flex"
                flexDirection={isScreenMd ? 'row' : 'column'}
                alignItems="center"
                width={1}
              >
                <Box
                  center
                  mr={isScreenMd ? 5 : 0}
                  width={isScreenMd ? '185px' : '100%'}
                  minWidth={185}
                >
                  <SelectField
                    defaultValue={selectedSellToken}
                    onChange={(value) => {
                      setDepositAmount(0);
                      setSelectedSellToken(value);
                    }}
                    options={
                      isZappable ? supportedTokenOptions : [selectedSellToken]
                    }
                  />
                </Box>
                <ButtonGroup width={1}>
                  <Box width={isScreenMd ? '185px' : '100%'}>
                    {/* 默认金库存款区域 */}
                    <AmountField
                      amount={depositAmount}
                      amountSetter={setDepositAmount}
                      gweiAmountSetter={setDepositGweiAmount}
                      maxAmount={
                        isZappable && sellToken
                          ? sellToken.balanceRaw
                          : tokenBalance
                      }
                      decimals={
                        isZappable && sellToken ? sellToken.decimals : decimals
                      }
                    />
                  </Box>
                  <Box width={isScreenMd ? '130px' : '100%'} ml={5}>
                    <ActionButton
                      disabled={
                        !vaultContract || !tokenContract || !!depositsDisabled
                      }
                      handler={() => (willZapIn ? zapperZap() : deposit())}
                      text={depositHasBeenApproved ? 'Deposit' : 'Approve'}
                      title="Deposit into vault"
                      showTooltipWhenDisabled
                      disabledTooltipText={
                        depositsDisabled ||
                        'Connect your wallet to deposit into vault'
                      }
                      showTooltipWhenEnabled={!depositHasBeenApproved}
                      enabledTooltipText={approvalExplainer}
                    />
                  </Box>
                </ButtonGroup>
              </Box>
              {zapperError &&
                zapperError.poolAddress === vaultAddress.toLowerCase() && (
                  <StyledErrorMessage>{zapperError.message}</StyledErrorMessage>
                )}
            </Box>
          </ActionGroup>

          <ActionGroup
            ml={isScreenMd ? '60px' : '0px'}
            direction={isScreenMd ? 'row' : 'column'}
          >
            <Box display="flex" flexDirection="column">
              <Box>
                <Balance
                  amount={vaultBalance}
                  prefix="Vault balance: "
                  decimalPlaces={balanceDecimalPlacesCount}
                />
              </Box>
              <Box
                display="flex"
                flexDirection={isScreenMd ? 'row' : 'column'}
                alignItems="center"
                width={1}
              >
                <Box
                  center
                  mr={isScreenMd ? 5 : 0}
                  width={isScreenMd ? '185px' : '100%'}
                  minWidth={185}
                >
                  {/* 提现2:默认的金库 */}
                  <AmountField
                    amount={withdrawalAmount}
                    amountSetter={setWithdrawalAmount}
                    gweiAmountSetter={setWithdrawalGweiAmount}
                    maxAmount={vaultBalanceOf}
                    decimals={decimals}
                  />
                </Box>
                <ButtonGroup width={1}>
                  <Box
                    center
                    mr={5}
                    width={isScreenMd ? '185px' : '100%'}
                    minWidth={150}
                  >
                    <SelectField
                      defaultValue={withdrawTokens[0]}
                      value={selectedWithdrawToken}
                      options={withdrawTokens}
                      onChange={(newValue) => {
                        setSelectedWithdrawToken(newValue);
                      }}
                    />
                  </Box>
                  <Box width={isScreenMd ? '130px' : '100%'}>
                    <ActionButton
                      className="action-button bold outline"
                      disabled={!vaultContract || !tokenContract}
                      handler={withdraw}
                      text="Withdraw"
                      title="Withdraw from vault"
                      showTooltipWhenDisabled
                      disabledTooltipText="Connect your wallet to withdraw from vault"
                    />
                  </Box>
                </ButtonGroup>
              </Box>
            </Box>
          </ActionGroup>
        </Box>
      </Wrapper>
    );
  }

  if (isMigratable) {
    //console.log('~~~~>5:', vault.symbol);

    // 如果是可以迁移的
    vaultControlsWrapper = (
      <Wrapper>
        <Box
          width={isScreenMd ? '160px' : '100%'}
          ml={isScreenMd ? '60px' : '0px'}
        >
          <MigrateVault vaultAddress={vaultAddress} />
        </Box>
        <Box width={isScreenMd ? '160px' : '100%'} ml={5}>
          <ActionButton
            className="action-button dark"
            disabled={!vaultContract || !tokenContract}
            handler={withdrawAll}
            text="Withdraw All"
            title="Withdraw balance from vault"
            showTooltipWhenDisabled
            disabledTooltipText="Connect your wallet to withdraw from vault"
            outlined={1}
          />
        </Box>
      </Wrapper>
    );
  }

  return vaultControlsWrapper;
}

function SelectField({ defaultValue, options, onChange }) {
  return (
    <StyledRoundedSelect
      defaultValue={defaultValue}
      options={options}
      onChange={onChange}
    />
  );
}

// 数量相关的组件
function AmountField({
  amount,
  amountSetter,
  gweiAmountSetter,
  maxAmount,
  decimals,
  placeholder,
  disabled,
  hideMaxButton,
  disabledStyle,
}) {
  return (
    <StyledRoundedInput
      value={amount}
      disabledStyle={disabledStyle}
      right={
        hideMaxButton ? null : (
          <MaxButton
            maxAmount={maxAmount}
            amountSetter={amountSetter}
            gweiAmountSetter={gweiAmountSetter}
            decimals={decimals}
          />
        )
      }
      placeholder={placeholder}
      disabled={disabled}
      onChange={(evt) => {

        amountSetter(evt.target.value);

        if (evt.target.value) {
          const gweiAmount = new BigNumber(evt.target.value)
            .multipliedBy(10 ** decimals)
            .toFixed(0);

          gweiAmountSetter(gweiAmount);
        } else {
          gweiAmountSetter(0);
        }
      }}
      maxValue={getNormalizedAmount(maxAmount, decimals)}
    />
  );
}

// 最大存款额度按钮
function MaxButton({ maxAmount, amountSetter, gweiAmountSetter, decimals }) {
  return (
    <MaxWrapper
      onClick={() => {
        const normalizedAmount = new BigNumber(maxAmount)
          .dividedBy(10 ** decimals)
          .toFixed(2);

        amountSetter(normalizedAmount);
        gweiAmountSetter(maxAmount);
      }}
    >
      Max
    </MaxWrapper>
  );
}

// 余额按钮
function Balance({ amount, prefix, decimalPlaces = 2, hideBalance }) {
  return (
    <div>
      {prefix}
      {hideBalance ? null : new BigNumber(amount).toFixed(decimalPlaces)}
    </div>
  );
}

// 行为按钮
function ActionButton({
  disabled,
  className,
  handler,
  title,
  text,
  disabledTooltipText,
  enabledTooltipText,
  showTooltipWhenDisabled,
  showTooltipWhenEnabled,
  outlined,
}) {
  return (
    <ButtonFilled
      disabled={disabled}
      className={className}
      onClick={() => handler()}
      color="primary"
      title={title}
      disabledTooltipText={disabledTooltipText}
      showTooltipWhenDisabled={showTooltipWhenDisabled}
      outlined={outlined}
      showTooltipWhenEnabled={showTooltipWhenEnabled}
      enabledTooltipText={enabledTooltipText}
    >
      {text}
    </ButtonFilled>
  );
}
